﻿#region

using System;
using System.Configuration;
using System.Linq;

#endregion

namespace BTL.Technology.Framework.Configuration
{
    public class SectionConfiguration : ConfigurationSection
    {
        [ConfigurationProperty("settings")]
        public SectionElementCollection Settings
        {
            get { return (SectionElementCollection) base["settings"]; }
        }

        public static T GetInstance<T>(string section)
            where T : new()
        {
            //Declare object
            var retValue = new T();

            //Read configuration for provided section
            var configurationSection = (SectionConfiguration) ConfigurationManager.GetSection(section);

            //return null if there is no section specified
            if (configurationSection == null) return retValue;

            //read the settings to the return object
            foreach (SectionConfigurationElement setting in configurationSection.Settings)
            {
                configurationSection.FillProperty(retValue, setting);
            }
            return retValue;
        }


        //TODO: move to Object helper and use cache
        private void FillProperty(object settingObject, SectionConfigurationElement element)
        {
            var objType = settingObject.GetType();
            var info =
                objType.GetProperties().FirstOrDefault(e => e.Name.ToLower() == element.Name.ToLower());
            if (info != null && info.CanWrite)
            {
                var provalue = Convert.ChangeType(element.Value, info.PropertyType);
                info.SetValue(settingObject, provalue, null);
            }
            else if (settingObject as ISectionConfiguration != null)
            {
                (settingObject as ISectionConfiguration).Add(element.Name, element.Value, element.KeyValuePairs);
            }
        }
    }
}